﻿using NineSeas.Models;
using Orchard;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using Orchard.Settings;
using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Users.Models;
using Contrib.Voting.Services;
using Orchard.Data;
using Contrib.Voting.Models;
using NineSeas.Extensions;
using Orchard.Core.Common.Models;

namespace NineSeas.Services
{
    public class AuthorService: IAuthorService
    {
        private readonly IOrchardServices _orchardServices;
        private readonly IVotingService _votingService;
        private readonly IRepository<ResultRecord> _resultRepository;

        public AuthorService(IOrchardServices orchardServices,
            IRepository<ResultRecord> resultRepository,
            IVotingService votingService)
        {
            this._orchardServices = orchardServices;
            this._votingService = votingService;
            this._resultRepository = resultRepository;
        }

        public IList<AuthorProfilePart> Search(ViewModels.AuthorSearchViewModel search, PaginationInfo paging)
        {
            var predicate = PredicateBuilder.True<AuthorProfilePartRecord>();

            if (!String.IsNullOrEmpty(search.Expression) && String.Compare(search.Expression.Trim(), "%") != 0)
            {
                string expression = search.Expression;
                if (!expression.EndsWith("%"))
                {
                    expression += "%";
                }

                if (!expression.StartsWith("%"))
                {
                    expression = "%" + expression;
                }

                predicate = predicate.And(a => a.DisplayName.Contains(expression));
            }
            else
            {
                predicate = predicate.And(a => a.DisplayName != null);
            }
            predicate = predicate.And(a => a.AvatarUrl != null && a.AvatarUrl != "" && a.BookCount > 0);

            paging.TotalRecords = _orchardServices.ContentManager.Query<AuthorProfilePart, AuthorProfilePartRecord>()
                .Where(predicate)
                .Count();

            var query = _orchardServices.ContentManager.Query<AuthorProfilePart, AuthorProfilePartRecord>()
                .Where(predicate);

            Expression<Func<AuthorProfilePartRecord, object>> orderByClause = null;
            if (!String.IsNullOrWhiteSpace(search.OrderBy))
            {
                if ("name".Equals(search.OrderBy, StringComparison.InvariantCultureIgnoreCase))
                {
                    orderByClause = a => a.DisplayName;
                }
                else if ("likes".Equals(search.OrderBy, StringComparison.InvariantCultureIgnoreCase))
                {
                    orderByClause = a => a.TotalLikes;
                }
                else
                {
                    orderByClause = a => a.CreatedUtc;
                }

                if (String.IsNullOrWhiteSpace(search.OrderDirection) || !search.OrderDirection.StartsWith("asc", StringComparison.InvariantCultureIgnoreCase))
                {
                    query = query.OrderByDescending(orderByClause);
                }
                else
                {
                    query = query.OrderBy(orderByClause);
                }
            }
            else
            {
                query = query.OrderByDescending(a => a.Id);
            }

            return query.Slice(paging.StartIndex, paging.PageSize.Value)
                    .ToList();
        }

        public AuthorProfilePart Get(int id)
        {
            return _orchardServices.ContentManager.Get<AuthorProfilePart>(id);
        }
    }
}